#include "sm_state_machine.h"

#include "stdio.h"
#include "State/agent.h"

////状态转移表
//static int SM_STATE_TRANSITION_TABLE[SM_EVENT_MAX+1][SM_STATE_MAX+1]=
//{
//    {-1,0,1,2,3,4,5},
//    {0,2,2,2,2,2,2},
//    {1,1,1,1,1,1,1},
//    {2,-1,-1,4,4,4,-1},
//    {3,-1,-1,-1,-1,5,-1},
//    {4,-1,-1,-1,-1,4,4},
//    {5,-1,-1,-1,-1,3,-1},
//    {6,0,0,0,0,0,0}
//};

////状态错误检查表
////0:可以接受该状态
////not 0:不可接受该状态
//static int SM_STATE_ERROR_CHECK_TABLE[SM_EVENT_MAX+1][SM_STATE_MAX+1]=
//{
//    {-1,0,1,2,3,4,5},
//    {0,0,0,0,0,0,0},
//    {1,0,0,0,0,0,0},
//    {2,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,0,0,0,SM4A_PRECONDITION_ERROR},
//    {3,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,0,SM4A_PRECONDITION_ERROR},
//    {4,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,0,0},
//    {5,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,SM4A_PRECONDITION_ERROR,0,SM4A_PRECONDITION_ERROR},
//    {6,0,0,0,0,0,0}
//};

////当前状态机
//static SM_STATE_MACHINE_STRUCT state_machine =
//{
//    SM_STATE_TERMINATED,
//    nullptr,
//    nullptr
//};

//记录事件个数
static int index = 0;
//状态机
static Agent state_agent;

//枚举转字符串
const char * type2str(IN SM_STATE_ENUM state)
{
    const char *str="";
    switch (state) {
    case SM_STATE_ERROR:
        str="SM_STATE_ERROR";
        break;
    case SM_STATE_TERMINATED:
        str="SM_STATE_TERMINATED";
        break;
    case SM_STATE_IDLE:
        str="SM_STATE_IDLE";
        break;
    case SM_STATE_QUEUE_EMPTY:
        str="SM_STATE_QUEUE_EMPTY";
        break;
    case SM_STATE_QUEUE_PARTY_FULL:
        str="SM_STATE_QUEUE_PARTY_FULL";
        break;
    case SM_STATE_QUEUE_FULL:
        str="SM_STATE_QUEUE_FULL";
        break;
    default:
        str="inValid";
        break;
    }

    return str;
}

const char * type2str(IN SM_EVENT_ENUM event)
{
    const char *str="";
    switch (event) {
    case SM_EVENT_INITIALIZE:
        str="SM_EVENT_INITIALIZE";
        break;
    case SM_EVENT_TERMINATE:
        str="SM_EVENT_TERMINATE";
        break;
    case SM_EVENT_QUEUE:
        str="SM_EVENT_QUEUE";
        break;
    case SM_EVENT_QUEUE_FULL:
        str="SM_EVENT_QUEUE_FULL";
        break;
    case SM_EVENT_GET_RESULT:
        str="SM_EVENT_GET_RESULT";
        break;
    case SM_EVENT_GET_RESULT_EMPTY:
        str="SM_EVENT_GET_RESULT_EMPTY";
        break;
    case SM_EVENT_ERROR:
        str="SM_EVENT_ERROR";
        break;
    default:
        str="inValid";
        break;
    }
    return str;
}

int sm_state_machine_create()
{
    int iResult = OK;
    printf("%s > ()\n",__func__);

    SM_STATE_ENUM sm_current_state;
    state_agent.get_current_state(&sm_current_state);
    cout<<"index="<<index<<",current state="<<type2str(sm_current_state)<<endl;

    printf("%s < () = 0x%x\n",__func__,iResult);
    return iResult;
}

int sm_state_machine_destory()
{
    int iResult = OK;
    printf("%s > ()\n",__func__);


    printf("%s < () = 0x%x\n",__func__,iResult);
    return iResult;
}


int sm_state_machine_check_transition(SM_EVENT_ENUM event, int *state_check_result)
{
    int iResult = OK;
    printf("%s > ()\n",__func__);

    //1.检查各种参数是否满足要求
    if(state_check_result == nullptr)
    {
        iResult = SM4A_NULL_POINTER_ERROR;
    }

    if(iResult == OK)
    {
        if(event <= SM_EVENT_MIN || event >= SM_EVENT_MAX)
        {
            iResult = SM4A_ST_PARAMETERS_ERROR;
        }
    }

    SM_STATE_ENUM current_state = SM_STATE_MIN;

    if(iResult == OK)
    {
        iResult = state_agent.get_current_state(&current_state);
    }

    //2.查看状态转移图检查结果
    if(iResult == OK)
    {
          if(event == SM_EVENT_INITIALIZE)
          {
             *state_check_result = state_agent.check_transition_event_initialize();
          }else if(event == SM_EVENT_TERMINATE)
          {
             *state_check_result = state_agent.check_transition_event_terminate();
          }else if(event == SM_EVENT_QUEUE)
          {
             *state_check_result = state_agent.check_transition_event_queue();
          }else if(event == SM_EVENT_QUEUE_FULL)
          {
             *state_check_result = state_agent.check_transition_event_queue_full();
          }else if(event == SM_EVENT_GET_RESULT)
          {
             *state_check_result = state_agent.check_transition_event_get_result();
          }else if(event == SM_EVENT_GET_RESULT_EMPTY)
          {
             *state_check_result = state_agent.check_transition_event_get_result_empty();
          }else if(event == SM_EVENT_ERROR)
          {
             *state_check_result = state_agent.check_transition_event_error();
          }

//        *state_check_result = (*state_machine.sm_error_check_table_p)[event+1][current_state+1];
    }

    printf("%s, (current_state=%s,event=%s,*state_check_result=0x%x)\n",
           __func__,type2str(current_state),type2str(event),*state_check_result);

    printf("%s < () = 0x%x\n",__func__,iResult);
    return iResult;
}

int sm_state_machine_perform_transition(SM_EVENT_ENUM event)
{
    int iResult = OK;
    printf("%s > ()\n",__func__);

    //1.检查各种参数是否满足要求
    if(iResult == OK)
    {
        if(event <= SM_EVENT_MIN || event >= SM_EVENT_MAX)
        {
            iResult = SM4A_ST_PARAMETERS_ERROR;
        }
    }

    SM_STATE_ENUM current_state = SM_STATE_MIN;


    //2.查看状态转移图检查结果
    if(iResult == OK)
    {
        iResult = state_agent.get_current_state(&current_state);
    }

    if(iResult == OK)
   {
       if(event <= SM_EVENT_MIN || event >= SM_EVENT_MAX)
       {
           iResult = SM4A_ST_PARAMETERS_ERROR;
       }
   }

    //3.进行状态转移
    SM_STATE_ENUM after_state = SM_STATE_MIN;
    if(iResult == OK)
    {
        if(event == SM_EVENT_INITIALIZE)
        {
           iResult = state_agent.perform_transition_event_initialize();
        }else if(event == SM_EVENT_TERMINATE)
        {
           iResult = state_agent.perform_transition_event_terminate();
        }else if(event == SM_EVENT_QUEUE)
        {
           iResult = state_agent.perform_transition_event_queue();
        }else if(event == SM_EVENT_QUEUE_FULL)
        {
           iResult = state_agent.perform_transition_event_queue_full();
        }else if(event == SM_EVENT_GET_RESULT)
        {
           iResult = state_agent.perform_transition_event_get_result();
        }else if(event == SM_EVENT_GET_RESULT_EMPTY)
        {
           iResult = state_agent.perform_transition_event_get_result_empty();
        }else if(event == SM_EVENT_ERROR)
        {
           iResult = state_agent.perform_transition_event_error();
        }
    }

    if(iResult == OK)
    {
        iResult = state_agent.get_current_state(&after_state);
    }

    index++;
    printf("%s, (index=%d,current_state=%s,event=%s,after_state=%s)\n",
           __func__,index,type2str(current_state),type2str(event),type2str(after_state));

    printf("%s < () = 0x%x\n",__func__,iResult);
    return iResult;
}
